In notebook 4 we examined how the fringe transmission of a point source changes for different across and along-slice positions on the detector. The exercise involved solely the peak intensity of the point sources. Here we check that the conclusions drawn apply for the different PSF locations. Remember that this test was done in notebook 2 for the point source etalon data and no variation in the position of the etalon lines was found. This fact is used as a visual guideline in the simulations that follow.
import funcs
import mrsobs
import numpy as np
from astropy.io import fits
from matplotlib import pyplot as plt
%matplotlib notebook
import warnings
warnings.simplefilter('ignore')
We load the images for one band of the MRS for different kinds of sources, including:
Additionally the pixel-to-wavelength calibration map and the pixel-to-along-slice position map are imported.
# Define paths to data
workDir = '/Users/ioannisa/Desktop/python/miri_devel/'
cdpDir = workDir+'cdp_data/'
d2cMapDir = workDir+'distortionMaps/'
lvl2path = workDir+'FM_data/LVL2/'
# Get data
band = '1A'
ext_etal_source_sci,ext_etal_source_bkg = mrsobs.FM_MTS_800K_BB_extended_source_through_etalon(lvl2path,band,etalon='ET1A')
point_source_sci_p1,point_source_bkg_p1 = mrsobs.FM_MTS_800K_BB_point_source_raster(lvl2path,position='middle',pointing='P1')
# Get wavelength calibration pixel map
d2cMaps = funcs.load_obj('d2cMaps_band{}'.format(band),path=d2cMapDir)
lambdaMap = d2cMaps['lambdaMap']
lambdaMap[lambdaMap==0] = np.nan
alphaMap = d2cMaps['alphaMap']
nslices = d2cMaps['nslices']
We subtract background exposures where available
# perform transform
ext_etal_source_bkgsubtr = ext_etal_source_sci-ext_etal_source_bkg
point_source_p1_bkgsubtr = point_source_sci_p1-point_source_bkg_p1
We perform an even-odd row signal correction to the data (caused by the read-out pattern of MIRI detector pixel rows)
ext_etal_source_oddevencorr = funcs.OddEvenRowSignalCorrection(ext_etal_source_bkgsubtr)
point_source_p1_oddevencorr = funcs.OddEvenRowSignalCorrection(point_source_p1_bkgsubtr)
Much like in notebook 2 we take the three slices that contain the PSF (slices with largest signal), determine the pixel trace that contains the peak of the PSF, and then take the two traces on the left and the right to probe the sides of the PSF.
Note that the expectation is not for the fringe transmission to be the same in different slices. Contrary to the etalon point source data which probed the physical (plane-parallel) etalon, we now probe the detector structure and its inhomogeneities.
# Pixel trace in MRS slice
ypos_sourcecenterslice,xpos_sourcecenterslice = funcs.detpixel_trace_compactsource(point_source_p1_oddevencorr,band,d2cMaps,offset_slice=0)
ypos_nearbyslice1,xpos_nearbyslice1 = funcs.detpixel_trace_compactsource(point_source_p1_oddevencorr,band,d2cMaps,offset_slice=-1)
ypos_nearbyslice2,xpos_nearbyslice2 = funcs.detpixel_trace_compactsource(point_source_p1_oddevencorr,band,d2cMaps,offset_slice=1)
xpos_offsets = [-2,-1,0,1,2]
# normalize signal
pointsource_norm = {}
pointsource_norm['slice6'] = funcs.norm_fringe(point_source_p1_oddevencorr[ypos_nearbyslice1,xpos_nearbyslice1],thres=0,min_dist=6,k=3,ext=3)
pointsource_norm['slice7'] = funcs.norm_fringe(point_source_p1_oddevencorr[ypos_sourcecenterslice,xpos_sourcecenterslice],thres=0,min_dist=6,k=3,ext=3)
pointsource_norm['slice8'] = funcs.norm_fringe(point_source_p1_oddevencorr[ypos_nearbyslice2,xpos_nearbyslice2],thres=0,min_dist=6,k=3,ext=3)
# let's look at the results
fig,axs = plt.subplots(2,1,figsize=(12,8))
axs[0].set_title('Extended etalon data',fontsize=20)
for plot in range(2):
axs[plot].plot(lambdaMap[ypos_nearbyslice1,xpos_nearbyslice1],ext_etal_source_oddevencorr[ypos_nearbyslice1,xpos_nearbyslice1],label='slice 6')
axs[plot].plot(lambdaMap[ypos_sourcecenterslice,xpos_sourcecenterslice],ext_etal_source_oddevencorr[ypos_sourcecenterslice,xpos_sourcecenterslice],label='slice 7')
axs[plot].plot(lambdaMap[ypos_nearbyslice2,xpos_nearbyslice2],ext_etal_source_oddevencorr[ypos_nearbyslice2,xpos_nearbyslice2],label='slice 8')
axs[plot].set_xlabel('Wavelength [micron]',fontsize=20)
axs[plot].set_ylabel('Signal [DN/sec]',fontsize=20)
axs[plot].legend(loc='upper right',fontsize=14)
axs[plot].tick_params(axis='both',labelsize=20)
axs[0].set_xlim(4.88,5.77)
axs[1].set_xlim(5.15,5.32)
plt.tight_layout()
fig,axs = plt.subplots(3,1,figsize=(12,13))
axs[0].set_title('Point source data',fontsize=20)
axs[0].plot(lambdaMap[ypos_nearbyslice1,xpos_nearbyslice1],point_source_p1_oddevencorr[ypos_nearbyslice1,xpos_nearbyslice1],label='slice 6')
axs[0].plot(lambdaMap[ypos_sourcecenterslice,xpos_sourcecenterslice],point_source_p1_oddevencorr[ypos_sourcecenterslice,xpos_sourcecenterslice],label='slice 7')
axs[0].vlines(lambdaMap[ypos_sourcecenterslice,xpos_sourcecenterslice][pointsource_norm['slice7'][1]],1,3.5,alpha=0.4,label='slice 7 fringe peaks')
axs[0].plot(lambdaMap[ypos_nearbyslice2,xpos_nearbyslice2],point_source_p1_oddevencorr[ypos_nearbyslice2,xpos_nearbyslice2],label='slice 8')
axs[0].plot(lambdaMap[ypos_nearbyslice1,xpos_nearbyslice1][:-1],pointsource_norm['slice6'][2][:-1])
axs[0].plot(lambdaMap[ypos_sourcecenterslice,xpos_sourcecenterslice][:-1],pointsource_norm['slice7'][2][:-1])
axs[0].plot(lambdaMap[ypos_nearbyslice2,xpos_nearbyslice2][:-1],pointsource_norm['slice8'][2][:-1])
axs[0].set_xlim(4.88,5.77)
axs[0].set_ylim(1,3.5)
for i in [1,2]:
axs[i].plot(lambdaMap[ypos_nearbyslice1,xpos_nearbyslice1],point_source_p1_oddevencorr[ypos_nearbyslice1,xpos_nearbyslice1]/pointsource_norm['slice6'][2],label='slice 6')
axs[i].plot(lambdaMap[ypos_sourcecenterslice,xpos_sourcecenterslice],point_source_p1_oddevencorr[ypos_sourcecenterslice,xpos_sourcecenterslice]/pointsource_norm['slice7'][2],label='slice 7')
axs[i].plot(lambdaMap[ypos_nearbyslice2,xpos_nearbyslice2],point_source_p1_oddevencorr[ypos_nearbyslice2,xpos_nearbyslice2]/pointsource_norm['slice8'][2],label='slice 8')
axs[i].set_ylim(0.78,1.05)
axs[2].vlines(lambdaMap[ypos_sourcecenterslice,xpos_sourcecenterslice][pointsource_norm['slice7'][1]],0.78,1.05,alpha=0.4)
for i in range(3):
axs[i].set_xlabel('Wavelength [micron]',fontsize=16)
axs[i].legend(loc='upper right',fontsize=12)
axs[i].tick_params(axis='both',labelsize=16)
axs[0].set_xlim(4.88,5.77)
axs[1].set_xlim(4.88,5.77)
axs[2].set_xlim(5.125,5.3)
axs[0].set_ylabel('Signal [DN/sec]',fontsize=16)
axs[1].set_ylabel('Normalized signal',fontsize=16)
axs[2].set_ylabel('Normalized signal',fontsize=16)
axs[2].set_title('<Zoomed view>',fontsize=16)
plt.tight_layout()
# normalize signal
pointsource_slice6_norm,pointsource_slice7_norm,pointsource_slice8_norm = [{} for i in range(3)]
for xpos_offset in xpos_offsets:
pointsource_slice6_norm['offset'+str(xpos_offset)] = funcs.norm_fringe(point_source_p1_oddevencorr[ypos_nearbyslice1,xpos_nearbyslice1+xpos_offset],thres=0,min_dist=6,k=1,ext=3)
pointsource_slice7_norm['offset'+str(xpos_offset)] = funcs.norm_fringe(point_source_p1_oddevencorr[ypos_sourcecenterslice,xpos_sourcecenterslice+xpos_offset],thres=0,min_dist=6,k=1,ext=3)
pointsource_slice8_norm['offset'+str(xpos_offset)] = funcs.norm_fringe(point_source_p1_oddevencorr[ypos_nearbyslice2,xpos_nearbyslice2+xpos_offset],thres=0,min_dist=6,k=1,ext=3)
# let's look at the results (slice 6)
fig,axs = plt.subplots(2,1,figsize=(12,8))
axs[0].set_title('Extended etalon data slice 6',fontsize=20)
for xpos_offset in xpos_offsets:
for plot in range(2):
axs[plot].plot(lambdaMap[ypos_nearbyslice1,xpos_nearbyslice1+xpos_offset],ext_etal_source_oddevencorr[ypos_nearbyslice1,xpos_nearbyslice1+xpos_offset],label='xpos offset {}'.format(xpos_offset))
axs[plot].set_xlabel('Wavelength [micron]',fontsize=20)
axs[plot].set_ylabel('Signal [DN/sec]',fontsize=20)
axs[plot].legend(loc='upper right',fontsize=10)
axs[plot].tick_params(axis='both',labelsize=20)
axs[0].set_xlim(4.88,5.77)
axs[0].set_ylim(0)
axs[1].set_xlim(5.196,5.274)
axs[1].set_ylim(0)
plt.tight_layout()
fig,axs = plt.subplots(3,1,figsize=(12,13))
axs[0].set_title('Slice 6',fontsize=20)
axs[0].vlines(lambdaMap[ypos_nearbyslice1,xpos_nearbyslice1][pointsource_slice6_norm['offset0'][1]],0,2.5,alpha=0.4,label='xpos offset 0 fringe peaks')
for xpos_offset in xpos_offsets:
axs[0].plot(lambdaMap[ypos_nearbyslice1,xpos_nearbyslice1+xpos_offset],pointsource_slice6_norm['offset'+str(xpos_offset)][0],label='xpos offset {}'.format(xpos_offset))
axs[0].plot(lambdaMap[ypos_nearbyslice1,xpos_nearbyslice1+xpos_offset],pointsource_slice6_norm['offset'+str(xpos_offset)][2])
norm_transmission = pointsource_slice6_norm['offset'+str(xpos_offset)][0]/pointsource_slice6_norm['offset'+str(xpos_offset)][2]
sel = (norm_transmission>0.7) & (norm_transmission<1.05)
axs[1].plot(lambdaMap[ypos_nearbyslice1,xpos_nearbyslice1+xpos_offset][sel],norm_transmission[sel],label='xpos offset {}'.format(xpos_offset))
axs[2].plot(lambdaMap[ypos_nearbyslice1,xpos_nearbyslice1+xpos_offset][sel],norm_transmission[sel],label='xpos offset {}'.format(xpos_offset))
axs[2].vlines(lambdaMap[ypos_nearbyslice1,xpos_nearbyslice1][pointsource_slice6_norm['offset0'][1]],0.7,1.05,alpha=0.4,label='xpos offset 0 fringe peaks')
axs[0].set_xlim(4.88,5.77)
axs[0].set_ylim(0,2.5)
axs[1].set_xlim(4.88,5.77)
axs[2].set_xlim(5.303,5.405)
axs[2].set_ylim(0.7,1.05)
axs[0].set_ylabel('Signal [DN/sec]',fontsize=20)
axs[1].set_ylabel('Signal [DN/sec]',fontsize=20)
axs[2].set_ylabel('Normalized signal',fontsize=20)
for plot in range(3):
axs[plot].set_xlabel('Wavelength [micron]',fontsize=20)
axs[plot].legend(loc='upper right',fontsize=10)
axs[plot].tick_params(axis='both',labelsize=20)
plt.tight_layout()
Let's look at the other slices.
# let's look at the results (slice 6)
fig,axs = plt.subplots(2,1,figsize=(12,8))
axs[0].set_title('Extended etalon data slice 7',fontsize=20)
for xpos_offset in xpos_offsets:
for plot in range(2):
axs[plot].plot(lambdaMap[ypos_sourcecenterslice,xpos_sourcecenterslice+xpos_offset],ext_etal_source_oddevencorr[ypos_sourcecenterslice,xpos_sourcecenterslice+xpos_offset],label='xpos offset {}'.format(xpos_offset))
axs[plot].set_xlabel('Wavelength [micron]',fontsize=20)
axs[plot].set_ylabel('Signal [DN/sec]',fontsize=20)
axs[plot].legend(loc='upper right',fontsize=10)
axs[plot].tick_params(axis='both',labelsize=20)
axs[0].set_xlim(4.88,5.77)
axs[0].set_ylim(0)
axs[1].set_xlim(5.196,5.274)
axs[1].set_ylim(0)
plt.tight_layout()
fig,axs = plt.subplots(3,1,figsize=(12,13))
axs[0].set_title('Slice 7',fontsize=20)
axs[0].vlines(lambdaMap[ypos_sourcecenterslice,xpos_sourcecenterslice][pointsource_slice7_norm['offset0'][1]],0,3.6,alpha=0.4,label='xpos offset 0 fringe peaks')
for xpos_offset in xpos_offsets:
axs[0].plot(lambdaMap[ypos_sourcecenterslice,xpos_sourcecenterslice+xpos_offset],pointsource_slice7_norm['offset'+str(xpos_offset)][0],label='xpos offset {}'.format(xpos_offset))
axs[0].plot(lambdaMap[ypos_sourcecenterslice,xpos_sourcecenterslice+xpos_offset],pointsource_slice7_norm['offset'+str(xpos_offset)][2])
norm_transmission = pointsource_slice7_norm['offset'+str(xpos_offset)][0]/pointsource_slice7_norm['offset'+str(xpos_offset)][2]
sel = (norm_transmission>0.7) & (norm_transmission<1.05)
axs[1].plot(lambdaMap[ypos_sourcecenterslice,xpos_sourcecenterslice+xpos_offset][sel],norm_transmission[sel],label='xpos offset {}'.format(xpos_offset))
axs[2].plot(lambdaMap[ypos_sourcecenterslice,xpos_sourcecenterslice+xpos_offset][sel],norm_transmission[sel],label='xpos offset {}'.format(xpos_offset))
axs[2].vlines(lambdaMap[ypos_sourcecenterslice,xpos_sourcecenterslice][pointsource_slice7_norm['offset0'][1]],0.7,1.05,alpha=0.4,label='xpos offset 0 fringe peaks')
axs[0].set_xlim(4.88,5.77)
axs[0].set_ylim(0,3.6)
axs[1].set_xlim(4.88,5.77)
axs[2].set_xlim(5.325,5.503)
axs[2].set_ylim(0.7,1.05)
axs[0].set_ylabel('Signal [DN/sec]',fontsize=20)
axs[1].set_ylabel('Signal [DN/sec]',fontsize=20)
axs[2].set_ylabel('Normalized signal',fontsize=20)
for plot in range(3):
axs[plot].set_xlabel('Wavelength [micron]',fontsize=20)
axs[plot].legend(loc='upper right',fontsize=10)
axs[plot].tick_params(axis='both',labelsize=20)
plt.tight_layout()
fig,axs = plt.subplots(2,1,figsize=(12,8))
axs[0].set_title('Extended etalon data slice 8',fontsize=20)
for xpos_offset in xpos_offsets:
for plot in range(2):
axs[plot].plot(lambdaMap[ypos_nearbyslice2,xpos_nearbyslice2+xpos_offset],ext_etal_source_oddevencorr[ypos_nearbyslice2,xpos_nearbyslice2+xpos_offset],label='xpos offset {}'.format(xpos_offset))
axs[plot].set_xlabel('Wavelength [micron]',fontsize=20)
axs[plot].set_ylabel('Signal [DN/sec]',fontsize=20)
axs[plot].legend(loc='upper right',fontsize=10)
axs[plot].tick_params(axis='both',labelsize=20)
axs[0].set_xlim(4.88,5.77)
axs[0].set_ylim(0)
axs[1].set_xlim(5.196,5.274)
axs[1].set_ylim(0)
plt.tight_layout()
fig,axs = plt.subplots(3,1,figsize=(12,13))
axs[0].set_title('Slice 8',fontsize=20)
axs[0].vlines(lambdaMap[ypos_nearbyslice2,xpos_nearbyslice2][pointsource_slice8_norm['offset0'][1]],0,2.6,alpha=0.4,label='xpos offset 0 fringe peaks')
for xpos_offset in xpos_offsets:
axs[0].plot(lambdaMap[ypos_nearbyslice2,xpos_nearbyslice2+xpos_offset],pointsource_slice8_norm['offset'+str(xpos_offset)][0],label='xpos offset {}'.format(xpos_offset))
axs[0].plot(lambdaMap[ypos_nearbyslice2,xpos_nearbyslice2+xpos_offset],pointsource_slice8_norm['offset'+str(xpos_offset)][2])
norm_transmission = pointsource_slice8_norm['offset'+str(xpos_offset)][0]/pointsource_slice8_norm['offset'+str(xpos_offset)][2]
sel = (norm_transmission>0.7) & (norm_transmission<1.05)
axs[1].plot(lambdaMap[ypos_nearbyslice2,xpos_nearbyslice2+xpos_offset][sel],norm_transmission[sel],label='xpos offset {}'.format(xpos_offset))
axs[2].plot(lambdaMap[ypos_nearbyslice2,xpos_nearbyslice2+xpos_offset][sel],norm_transmission[sel],label='xpos offset {}'.format(xpos_offset))
axs[2].vlines(lambdaMap[ypos_nearbyslice2,xpos_nearbyslice2][pointsource_slice8_norm['offset0'][1]],0.7,1.05,alpha=0.4,label='xpos offset 0 fringe peaks')
axs[0].set_xlim(4.88,5.77)
axs[0].set_ylim(0,2.6)
axs[1].set_xlim(4.88,5.77)
axs[2].set_xlim(5.135,5.27)
axs[2].set_ylim(0.7,1.05)
axs[0].set_ylabel('Signal [DN/sec]',fontsize=20)
axs[1].set_ylabel('Signal [DN/sec]',fontsize=20)
axs[2].set_ylabel('Normalized signal',fontsize=20)
for plot in range(3):
axs[plot].set_xlabel('Wavelength [micron]',fontsize=20)
axs[plot].legend(loc='upper right',fontsize=10)
axs[plot].tick_params(axis='both',labelsize=20)
plt.tight_layout()
Where do the extended source fringes "stand" with respect to the point source fringes? We know that the former do not shift in along-slice direction, but do the position of the fringe peaks match that of the point source fringes?